package com.edu.framework.websocket.service;


import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONArray;
import com.edu.common.utils.LogUtils;
import com.edu.common.utils.bean.BeanUtils;
import com.edu.framework.websocket.WebSocketHolder;
import com.edu.framework.websocket.message.base.Response;
import com.edu.framework.websocket.message.info.CanTeenVO;
import com.edu.framework.websocket.message.info.ClassVO;
import com.edu.framework.websocket.message.info.InfoRequest;
import com.edu.framework.websocket.message.registinfo.RegistInfoRequest;
import com.edu.framework.websocket.message.terminal.TerminalRequest;
import com.edu.framework.websocket.message.terminal.TerminalVO;
import com.edu.system.domain.TCanteen;
import com.edu.system.domain.TClass;
import com.edu.system.domain.TTerminal;
import com.edu.system.service.ISysDictDataService;
import com.edu.system.service.ITCanteenService;
import com.edu.system.service.ITClassService;
import com.edu.system.service.ITTerminalService;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class BaseInfoService {


    @Autowired
    private ISysDictDataService dictDataService;

    @Autowired
    private ITCanteenService canteenService;

    @Autowired
    private ITClassService classService;

    @Autowired
    private ITTerminalService terminalService;
    @Resource
    private TerminalService wsTerminalService;

    @Value("${image.host}")
    private String imageHost;

    /**
     * 机器注册
     *
     * @param info
     * @return
     */
    public Response regist(TerminalVO info) {

        String type = info.getType();
        Long locationId = info.getLocationId();
        String location = "";
        TerminalVO terminalVO = new TerminalVO();


        if ("班牌".equals(type)) {
            // locationId 教室id
            TClass tClass = this.classService.selectTClassByRoomId(locationId);
            ClassVO classVO = new ClassVO();
            BeanUtils.copyBeanProp(classVO, tClass);
            // 使用教室id、name
            classVO.setName(classVO.getRoomName());
            classVO.setId(classVO.getRoomId());

            terminalVO.setClassVO(classVO);
            location = classVO.getRoomName();

        } else {
            TCanteen canteen = this.canteenService.selectTCanteenById(locationId);
            CanTeenVO canTeenVO = new CanTeenVO();
            BeanUtils.copyBeanProp(canTeenVO, canteen);
            terminalVO.setCanTeenVO(canTeenVO);
            location = canteen.getName();
        }

        TTerminal query = new TTerminal();
        query.setCode(info.getCode());
        List<TTerminal> list = terminalService.selectTTerminalList(query);

        // 如果code已经有记录 则更新
        Long id = null;
        if (CollectionUtils.isNotEmpty(list)) {
            TTerminal terminal = list.get(0);
            terminal.setLocation(location);
            terminal.setLocationId(locationId);
            terminal.setType(info.getType());
            terminalService.updateTTerminal(terminal);
            id = terminal.getId();
            BeanUtils.copyBeanProp(terminalVO, terminal);
        } else {
            query.setType(info.getType());
            query.setLocation(location);
            query.setLocationId(locationId);
            terminalService.insertTTerminal(query);
            id = query.getId();
            BeanUtils.copyBeanProp(terminalVO, query);
        }
        // 立即推送一次开关机设置
        Long finalId = id;
        CompletableFuture.runAsync(() -> wsTerminalService.scheduleShutDown(new Long[]{finalId}));

        return Response.ok(TerminalRequest.TYPE, TerminalRequest.RESP_KEY, terminalVO);
    }

    public Response getBindInfo(String code) {
        TTerminal terminal = this.terminalService.selectTTerminalByCode(code);
        if (Objects.isNull(terminal)){
            return Response.ok(RegistInfoRequest.TYPE, RegistInfoRequest.RESP_KEY, new TerminalVO());
        }

        String type = terminal.getType();
        Long locationId = terminal.getLocationId();
        TerminalVO terminalVO = convertToTerminalVO(terminal);
        if ("班牌".equals(type)) {
            TClass tClass = this.classService.selectTClassByRoomId(locationId);
            if (StrUtil.isNotBlank(tClass.getImage())){
                tClass.setImage(LogUtils.mergeHost(imageHost, tClass.getImage()));
            }
            ClassVO classVO = new ClassVO();
            BeanUtils.copyBeanProp(classVO, tClass);
            // 兼容前端，要教室名称
            classVO.setName(classVO.getRoomName());
            classVO.setId(classVO.getRoomId());
            terminalVO.setClassVO(classVO);
        } else {
            TCanteen canteen = this.canteenService.selectTCanteenById(locationId);
            CanTeenVO canTeenVO = new CanTeenVO();
            BeanUtils.copyBeanProp(canTeenVO, canteen);
            terminalVO.setCanTeenVO(canTeenVO);
        }

        return Response.ok(RegistInfoRequest.TYPE, RegistInfoRequest.RESP_KEY, terminalVO);
    }


    private TerminalVO convertToTerminalVO(TTerminal entry) {
        TerminalVO vo = new TerminalVO();
        BeanUtils.copyBeanProp(vo, entry);
        return vo;
    }


    public JSONArray getInfoByType(String type) {
        if ("班牌".equals(type)) {
            List<TClass> tClasses = this.classService.selectTClassList(new TClass());
            return JSONArray.copyOf(convertToClassVO(tClasses));
        }
        if ("食堂".equals(type)) {
            List<TCanteen> tCanteens = this.canteenService.selectTCanteenList(new TCanteen());
            return JSONArray.copyOf(convertToCanTeenVO(tCanteens));
        }
        return new JSONArray();
    }


    private List<ClassVO> convertToClassVO(List<TClass> list) {
        List<ClassVO> result = new ArrayList<>();
        if (CollectionUtils.isEmpty(list)) {
            return result;
        }
        for (TClass tClass : list) {
            ClassVO vo = new ClassVO();
            BeanUtils.copyBeanProp(vo, tClass);
            // 返回教室的id、name
            vo.setId(vo.getRoomId());
            vo.setName(vo.getRoomName());
            vo.setImage(LogUtils.mergeHost(imageHost, tClass.getImage()));
            result.add(vo);
        }
        return result;
    }

    private List<CanTeenVO> convertToCanTeenVO(List<TCanteen> list) {
        List<CanTeenVO> result = new ArrayList<>();
        if (CollectionUtils.isEmpty(list)) {
            return result;
        }
        for (TCanteen canteen : list) {
            CanTeenVO vo = new CanTeenVO();
            BeanUtils.copyBeanProp(vo, canteen);
            result.add(vo);
        }
        return result;
    }

    public void pushInfo(Long locationId, String type){
        TTerminal t = new TTerminal();
        t.setType(type);
        t.setLocationId(locationId);
        List<TTerminal> tTerminals = this.terminalService.selectTTerminalList(t);
        if (CollectionUtils.isNotEmpty(tTerminals)){
            String code = tTerminals.get(0).getCode();
            Response bindInfo = getBindInfo(code);
            try {
                WebSocketHolder.send(code, bindInfo);
            } catch (Exception e){
                log.error("下发机器信息失败", e);
            }
        }
    }

    public void pushDelete(List<String> codes){
        codes.forEach(code -> {
            Response bindInfo = getBindInfo(code);
            try {
                WebSocketHolder.send(code, bindInfo);
            } catch (Exception e){
                log.error("下发机器信息失败", e);
            }
        });
    }


}
